<template>
  <div class="gantt-gadget" :id="id">
    <Portal to="right-disable"
            v-loading="loading"
            :disabled="!isSetting">
      <DashboardInterceptConsumer :gadgetId="id"
                                  shadow="hover"
                                  @mouseenter="mouseenter(true)"
                                  @mouseleave="mouseenter(false)"
                                  :style="{height: gadgetHeight + 'px',}">
        <el-card shadow="never"
                 :style="{height: gadgetHeight + 'px',}">
          <div class="cardHeader"
               @mouseenter="mouseenter(true)"
               @mouseleave="mouseenter(false)"
               v-if="widgetName">
            <GadgetTitle :gadgetSetting="settings"
                         :widgetName="widgetName"></GadgetTitle>
            <div>

              <MoreMenu :slicer='slicer'
                        :gadgetId='id'
                        :gadgetType='gadgetInfo.com'
                        @updateQuery="query"
                        :widgetName="widgetName"
                        :businessType="gadgetInfo.businessType"
                        :id="gadgetInfo.id"
                        @showQueryModel="showQueryModel"
                        @fullScreen="fullScreen" />
            </div>
          </div>
          <div :style="{height: gadgetHeight + 'px',width: '100%',}">
            <Gantt :dataSource="dataSource"
                  :dateFormat="dateFormat"
                  :timezone="timezone"
                  :allowResizing="true"
                  :key="ganttKey"
                  :taskFields="taskFields"
                  :columns="columns"
                  :height="gadgetHeight-70+'px'"
                  :width="'100%'"
                  :includeWeekend="true"
                  :selectionSettings="selectionSettings"
                  :timelineSettings="timelineSettings" />
          </div>

          <Lastupdatetime v-if="currentTime"
                          :currentTime="currentTime"
                          :linkedDatasetList="linkedDatasetList"
                          :errorStatus="errorStatus"
                          @updateQuery="query()"></Lastupdatetime>
        </el-card>

      </DashboardInterceptConsumer>

    </Portal>
    <DrillThrough :gadgetId='id'
                  :pageId='pageId'
                  :slicer="slicer"
                  :queryId="queryId"
                  ref="drill-through"
                  :widgetName='widgetName' />
    <Model :showSetting="isSetting"
           @queryModelClosed="queryModelClosed"
           :selectFields="selectFields"
           :dataInfo="{
              businessId: pageId,
              gadgetId: id,
              gadgetType: 'ganttgadget',
              gadgetSetting:settings
            }"
           :updateGadget="upgradeGadgetSetting" />
  </div>
</template>
<script>
import mixinGadgetViewModule from '@/mixins/gadget-view-module'
import mixinFormatViewModule from '@/mixins/format-gadget-view-module'
import Lastupdatetime from '@/components/last-update-time/index.vue'
import { omit, get, values, pick } from 'lodash'
import Emitter from '@/mixins/emitter'
import Gantt from './gantt.vue'
import { v4 } from 'uuid'
import { taskFields } from './index.schema'
// import { GlobalTimeformat } from '@/utils/common'

export default {
  name: 'GanttGadget',
  components: {
    Lastupdatetime,
    Gantt,
    Model: () => import('@/components/gadget/query-model/query-model')
  },
  mixins: [mixinGadgetViewModule, mixinFormatViewModule, Emitter],
  props: {
    dataInfo: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      currentTime: null,
      loading: false,
      queryId: '',

      isSetting: false,
      settings: {},
      selectFields: [],
      widgetName: undefined,
      linkedDatasetList: [],
      data: [],
      ganttKey: v4(),
      selectionSettings: {
        type: 'Multiple'
      },
      dateFormat: "MM/dd/yyyy hh:mm:ss a"
    }
  },
  computed: {
    timezone () {
      return `${this.$store.state.user.timezoneId}`
    },
    dataSource () {
      const group = get(this.settings, 'group') || {}
      const { id, name, child, startDate, endDate } = this.taskFields
      const fields = values(this.taskFields)

      if (group.show && group.field) {
        return this.data.reduce((result, record) => {
          const findGroup = result.find(i => i[name] === record[group.field])
          const s = record[startDate]
          const e = record[endDate]
          if (findGroup) {
            let item = {
              ...pick(record, fields),
              id: record[id] || v4()
            }
            if (record[startDate]) {
              item[startDate] = s
            }
            if (record[endDate]) {
              item[endDate] = e
            }
            if (record[name]) {
              findGroup[child].push(item)
            }
          } else {
            // const columnFields = this.columns.map(i => i.field)
            const item = {
              id: record[id] || v4(),
              // ...pick(record, columnFields),
              [name]: record[group.field],
              [child]: []
            }
            if (record[name]) {
              let re = {
                ...pick(record, fields),
                id: record[id] || v4()
              }
              if (record[startDate]) {
                re[startDate] = s
              }
              if (record[endDate]) {
                re[endDate] = e
              }
              if (record[name]) {
                item[child].push(re)
              }
            }
            result.push(item)
          }
          return result
        }, [])
      }

      if (!this.columns.length) {
        return []
      }
      return this.data.map(i => {
        return {
          ...pick(i, fields),
          [startDate]: i[startDate],
          [endDate]: i[endDate],
          id: i[id] || v4()
        }
      })
    },
    taskFields () {
      const group = get(this.settings, 'group') || {}

      return this.columns.filter(i => i.taskField || i.field).reduce((result, record) => {
        return {
          ...result,
          [record.taskField]: record.field
        }
      }, group.show ? taskFields : omit(taskFields, 'child'))
    },
    columns () {
      const columns = this.settings.columns || []
      return columns.filter(i => i.show).map(i => ({
        headerText: i.headerText,
        taskField: i.taskField,
        field: i.field,
      }))
    },

    timelineSettings () {
      let topTier = this.settings.topTier || {}
      let bottomTier = this.settings.bottomTier || {}
      if (!topTier.show) {
        topTier = { unit: 'None' }
      }
      if (!bottomTier.show) {
        bottomTier = { unit: 'None' }
      }

      return {
        topTier,
        bottomTier,
        timelineUnitSize: !bottomTier.show && topTier.show ? 150 : 33
      }
    }
  },
  watch: {

    taskFields: {
      handler () {
        this.ganttKey = v4()
      },
      deep: true
    },
    timelineSettings: {
      handler (data) {
        if (data.bottomTier.unit === 'Day') {
          this.dateFormat = 'dd/MM/yyyy'
        }
        if (data.bottomTier.unit === 'Hour') {
          this.dateFormat = 'dd/MM/yyyy hh:mm:ss a'
        }
        if (data.bottomTier.unit === 'Month') {
          this.dateFormat = 'MM/yyyy'
        }
        if (data.bottomTier.unit === 'Year') {
          this.dateFormat = 'yyyy'
        }
        if (data.bottomTier.unit === 'Week') {
          this.dateFormat = 'dd/MM/yyyy'
        }
        this.ganttKey = v4()
      },
      deep: true
    },
    columns: {
      handler () {
        this.ganttKey = v4()
      },
      deep: true
    }
  },
  created () {
    this.gadgetHeight = this.pageFrom === 'reportLayoutFullScreen' ? window.screen.availHeight-100  : this.pageFromType === 'report' ? ((this.gadgetInfo.h * (this.rolHeight+10)-10) - 5) : this.pageFrom === 'reportLayout' ? ((this.gadgetInfo.h * 20) + 30) : ((this.gadgetInfo.h * 23) - 45)
    this.subscribeMessage('runReport', () => {
      this.query(this.refreshCount > 0 ? 'auto' : false)
      this.refreshCount = this.refreshCount + 1
    })
  },
  methods: {
    setHeight () {
      document.querySelector('.' + this.randomId + '>iframe').style.height = (this.gadgetHeight - 20) + 'px'
    },
    queryModelClosed () {
      this.isSetting = false
      this.query()
    },
    queryModelPreview () {
      this.query(true)
    },
    showQueryModel () {
      this.isSetting = true
    },

    resized (i, newH, newW, newHPx, newWPx) {
      this.gadgetHeight = newHPx
      this.gadgetWidth = newWPx
    },
    async query (e) {
      try {
        if (e !== 'auto') {
          this.loading = true
        }
        let tempObj = this.returnReportLinkParam()
        if (tempObj['name'] && this.slicer['name'] && tempObj['name'] === this.slicer['name']) delete this.slicer['name']
        const params = {
          ...omit(this.slicer, 'id'),
          code: this.code,
          gadgettype: this.wgadgettype,
          widgetName: this.wName,
          pageId: this.pageId,
          gadgetId: this.id,
          type: this.filterType,
          slicer: { ...this.slicer },
          filter: this.getFilterStr()
        }
        const { data: response } = await this.$interface.reports.getReportDataInfo(params)
        this.verifyHasData(response)

        if (response.code !== 0) {
          throw response.msg
        }

        this.linkedDatasetList = response.datasetSync || []
        this.selectFields = response.selectFields || []
        this.data = response.data || []
        this.settings = response.config || {}
        this.widgetName = response.name || this.settings.headerTitle
      } catch (error) {
        this.isHasData = false
        this.data = []
        this.settings = {}
        this.taskFields = []
        if (error.response && error.response.status === 504) {
          this.errorStatus = '504'
          this.gadgetMessageBus.$emit(this.pageId + 'stopautorefresh')
        }
      } finally {
        this.currentTime = new Date()
        this.loading = false
        this.autoRefreshQuery(e)
        this.updateGadgetLoadingStatus(!this.loading)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.gantt-gadget {
  .el-card {
    ::v-deep .el-card__body {
      height: 100%;
      display: flex;
      flex-direction: column;
      padding: 0px !important;
      position: relative;
    }
    ::v-deep .el-divider--horizontal {
      margin: 3px 0 !important;
    }
    .cardHeader {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 6px 20px;
      border-bottom: 1px solid #eee;
      position: relative;
    }
  }
}
</style>
